package com.yixin.hospital.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yixin.hospital.common.ApiResult;
import com.yixin.hospital.common.Constant;
import com.yixin.hospital.entity.bo.PageInfo;
import com.yixin.hospital.entity.bo.UserDeptWorkAddressJobOffice;
import com.yixin.hospital.entity.domain.*;
import com.yixin.hospital.entity.dto.req.auditmanager.AddAuditFlowReqDTO;
import com.yixin.hospital.entity.dto.req.user.LoginReqDTO;
import com.yixin.hospital.entity.dto.req.user.RegisterReqDTO;
import com.yixin.hospital.entity.dto.req.user.UserEditReqDTO;
import com.yixin.hospital.entity.vo.*;
import com.yixin.hospital.enums.*;
import com.yixin.hospital.mapper.extend.UserExtendMapper;
import com.yixin.hospital.service.*;
import com.yixin.hospital.service.extend.AuditFlowPresetExtendService;
import com.yixin.hospital.utils.AESUtil;
import com.yixin.hospital.utils.CaffeineUtils;
import com.yixin.hospital.utils.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import static com.yixin.hospital.common.Constant.USER_CACHE;
import static com.yixin.hospital.enums.ResponseCodeEnum.USER_EXIT;

@RestController
@RequestMapping("/user")
@Api(value = "员工管理", tags = "员工管理")
@Slf4j
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private UserMenuService userMenuService;
    @Resource
    private UserExtendMapper userExtendMapper;
    @Resource
    private JobDutyService jobDutyService;
    @Resource
    JobDutyMenuService jobDutyMenuService;
    @Resource
    AuditFlowPresetExtendService auditFlowPresetExtendService;
    @Resource
    AuditFlowDetailService auditFlowDetailService;
    @Resource
    AuditFlowService auditFlowService;
    @Resource
    DeptService deptService;
    @Resource
    WorkAddressService workAddressService;
    @Resource
    UserDeptWorkAddressService userDeptWorkAddressService;
    @Resource
    JobOfficeService jobOfficeService;
    @Resource
    UserTmpDeptService userTmpDeptService;
    @Resource
    DrugDepositoryUserAuthService drugDepositoryUserAuthService;
    @Resource
    DrugDepositoryService drugDepositoryService;

    @Value("${ip.white.list}")
    private List<String> ipWhiteList;

    @PostMapping("/register")
    @ApiOperation(value = "注册")
    @Transactional
    public ApiResult<?> register(@Valid @RequestBody RegisterReqDTO registerReqDTO) throws Exception {
        // 查询用户是否已注册
        LambdaQueryWrapper<User> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.eq(User::getPhone, registerReqDTO.getPhone());
        User one = userService.getOne(userQueryWrapper);
        if (one != null) {
            List<AuditFlow> auditFlows = auditFlowService.list(new LambdaQueryWrapper<AuditFlow>().eq(AuditFlow::getFlowNo, "ZC" + one.getId()));
            long finishCount = auditFlows.stream().filter(one1 -> AuditStatusEnum.FINISH.getCode().equals(one1.getStatus())).count();
            if (finishCount != 0) return ApiResult.error(USER_EXIT);
            long count = auditFlows.stream().filter(one1 -> AuditStatusEnum.AUDITING.getCode().equals(one1.getStatus())).count();
            if (count != 0) return ApiResult.error(ResponseCodeEnum.WAIT_AUDIT);
        }
        User user = new User();
        BeanUtils.copyProperties(registerReqDTO, user);
        String sexNum = registerReqDTO.getIdCard().substring(16, 17);
        user.setSex("1".equals(sexNum) ? "男" : "女");
        user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8)));
        //AES加密
        user.setAesPassword(AESUtil.encrypt(registerReqDTO.getPassword(), AESUtil.SECRET_KEY));
        user.setCreatedBy(registerReqDTO.getName());
        user.setUpdatedBy(registerReqDTO.getName());
        user.setJobNumber("XXXXXXXXXXX");//todo
        userService.save(user);
        saveAudit(user.getId(), user.getName(), "ZC" + user.getId().toString(), registerReqDTO.getAuditUserIds());
        return ApiResult.success();
    }

    private void saveAudit(Long userId, String userName, String code, List<Long> auditUserIds) {
        // 添加审批流
        AddAuditFlowReqDTO addAuditFlowReqDTO = new AddAuditFlowReqDTO();
        addAuditFlowReqDTO.setTitle(FlowNoPrefixEnum.REGISTER.getMsg());
        addAuditFlowReqDTO.setBusinessCode(BusinessEnum.REGISTER.getCode());
        addAuditFlowReqDTO.setAuditUserIds(auditUserIds);
        addAuditFlowReqDTO.setUserId(userId);
        addAuditFlowReqDTO.setUserName(userName);
        addAuditFlowReqDTO.setFlowNo(code);
        addAuditFlowReqDTO.setMessageType(MessageTypeEnum.REGISTER.getCode());

        auditFlowPresetExtendService.addAuditFlow(addAuditFlowReqDTO);
    }

    @PostMapping("/login")
    @ApiOperation(value = "登录")
    public ApiResult<LoginVO> login(@Valid @RequestBody LoginReqDTO loginReqDTO, HttpServletRequest request) {
        String ip = ServletUtil.getClientIP(request);
//        if (!ipWhiteList.contains(ip)) {
//            log.error("用户在该ip不允许登录, ip is {}", ip);
//            return ApiResult.error(ILLEGAL_IP);
//        }
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, loginReqDTO.getPhone());
        User user = userService.getOne(queryWrapper);
        if (user == null) {
            return ApiResult.error(ResponseCodeEnum.USER_NOT_EXIST);
        }
        // 查询是否已审批通过
        List<AuditFlow> auditFlows = auditFlowService.list(new LambdaQueryWrapper<AuditFlow>().eq(AuditFlow::getFlowNo, "ZC" + user.getId()));
        long count = auditFlows.stream().filter(one -> AuditStatusEnum.FINISH.getCode().equals(one.getStatus())).count();
        if (count == 0) return ApiResult.error(ResponseCodeEnum.WAIT_AUDIT);

        String password = DigestUtils.md5DigestAsHex(loginReqDTO.getPassword().getBytes(StandardCharsets.UTF_8));
        if (!password.equals(user.getPassword())) {
            return ApiResult.error(ResponseCodeEnum.PASSWORD_INCORRECT);
        }
        String token = JwtUtil.createToken(user);
        LoginVO registerResDTO = new LoginVO();
        registerResDTO.setToken(token);

        // 将用户登录信息存储在本地缓存
        List<UserDeptWorkAddressJobOffice> list = (List<UserDeptWorkAddressJobOffice>) CaffeineUtils.get(USER_CACHE);
        if (list == null) list = new ArrayList<>();
        list = list.stream().filter(obj -> !obj.getUserId().equals(user.getId())).collect(Collectors.toList());
        UserDeptWorkAddressJobOffice userDeptWorkAddressJobOffice = new UserDeptWorkAddressJobOffice();
        userDeptWorkAddressJobOffice.setDeptId(loginReqDTO.getDeptId());
        userDeptWorkAddressJobOffice.setJobDutyId(loginReqDTO.getJobDuty());
        userDeptWorkAddressJobOffice.setIsVisit(loginReqDTO.getIsVisit());
        userDeptWorkAddressJobOffice.setWorkAddressId(loginReqDTO.getWorkAddress());
        userDeptWorkAddressJobOffice.setJobOfficeId(loginReqDTO.getJobOffice());
        userDeptWorkAddressJobOffice.setUserId(user.getId());
        list.add(userDeptWorkAddressJobOffice);
        CaffeineUtils.put(USER_CACHE, list);

        return ApiResult.success(registerResDTO);
    }

    @GetMapping("/list")
    @ApiOperation(value = "员工列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "姓名", paramType = "query"),
            @ApiImplicitParam(name = "phone", value = "手机号", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "状态", paramType = "query"),
            @ApiImplicitParam(name = "menu", value = "权限", paramType = "query"),
            @ApiImplicitParam(name = "jobDutyParam", value = "职务", paramType = "query"),
    })
    public ApiResult<PageInfo<UserListVO>> list(@RequestParam int currentPage, @RequestParam int pageSize, @RequestParam(required = false) String name,
                                                @RequestParam(required = false) Long jobId, @RequestParam(required = false) Long jobTitleId,
                                                @RequestParam(required = false) Long queryJobDutyId, @RequestParam(required = false) Integer status,
                                                HttpServletRequest request) {
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
        User user = userService.getById(userId);
        IPage<UserListVO> page = userExtendMapper.pageVo(Page.of(currentPage, pageSize), name, jobId, jobTitleId, queryJobDutyId, status);
        List<UserListVO> records = page.getRecords();
        for (UserListVO record : records) {
            if (StringUtils.isNotBlank(record.getJobDuty())) {
                List<JobDutyVO> jobDutyList = new ArrayList<>();
                for (String jobDutyId : record.getJobDuty().split(",")) {
                    JobDutyVO jobDutyVO = new JobDutyVO();
                    JobDuty jobDuty = jobDutyService.getById(jobDutyId);
                    BeanUtils.copyProperties(jobDuty, jobDutyVO);
                    Dept tmpDept = deptService.getById(jobDutyVO.getDeptId());
                    jobDutyVO.setDeptName(tmpDept.getName());
                    jobDutyList.add(jobDutyVO);
                }
                record.setJobDutyList(jobDutyList);
            }
            // 查询用户是否能审批
            LambdaUpdateWrapper<AuditFlowDetail> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(AuditFlowDetail::getFlowNo, "ZC" + record.getId());
            wrapper.eq(AuditFlowDetail::getStatus, AuditDetailStatusEnum.AUDIT_ME.getCode());
            AuditFlowDetail auditFlowDetail = auditFlowDetailService.getOne(wrapper);
            if (Objects.nonNull(auditFlowDetail)) {
                if (user.getId().equals(auditFlowDetail.getAuditUserId())) {
                    record.setCanAudit(true);
                }
            }
        }

        PageInfo<UserListVO> pageInfo = new PageInfo<>();
        BeanUtils.copyProperties(page, pageInfo);
        return ApiResult.success(pageInfo);
    }

    @GetMapping("/allList")
    @ApiOperation(value = "所有员工下拉框")
    public ApiResult<?> allList() {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(User::getName);
        return ApiResult.success(userService.list(queryWrapper));
    }

    @GetMapping("/list-user-detail/{userId}")
    @ApiOperation(value = "列表用户详情")
    public ApiResult<UserDetailVO> listUserDetail(@PathVariable Long userId, HttpServletRequest request) throws Exception {
        UserDetailVO detail = userExtendMapper.detail(userId);
        //明文显示用户密码
        detail.setPassword(AESUtil.decrypt(detail.getAesPassword(), AESUtil.SECRET_KEY));
        if (StringUtils.isNotBlank(detail.getJobDuty())) {
            List<JobDutyVO> jobDutyList = new ArrayList<>();
            for (String jobDutyId : detail.getJobDuty().split(",")) {
                JobDutyVO jobDutyVO = new JobDutyVO();
                JobDuty jobDuty = jobDutyService.getById(jobDutyId);
                BeanUtils.copyProperties(jobDuty, jobDutyVO);
                Dept tmpDept = deptService.getById(jobDutyVO.getDeptId());
                jobDutyVO.setDeptName(tmpDept.getName());
                jobDutyList.add(jobDutyVO);
            }
            detail.setJobDutyList(jobDutyList);
        }
        if (StringUtils.isNotBlank(detail.getJobOffice())) {
            detail.setJobOfficeList(Arrays.asList(detail.getJobOffice().split(",")).stream().map(Long::parseLong).collect(Collectors.toList()));
        }

        // 查询用户所有菜单权限
        LambdaQueryWrapper<UserMenu> umQueryWrapper = new LambdaQueryWrapper<>();
        umQueryWrapper.eq(UserMenu::getUserId, userId);
        List<UserMenu> list = userMenuService.list(umQueryWrapper);
        List<Long> userMenus = list.stream().map(UserMenu::getMenuId).collect(Collectors.toList());
        detail.setUserMenus(userMenus);
        // 查询用户部门以及工作地点
        List<UserDeptWorkAddress> userDeptWorkAddressList = userDeptWorkAddressService.list(new LambdaQueryWrapper<UserDeptWorkAddress>().eq(UserDeptWorkAddress::getUserId, userId));
        List<UserDeptAndWorkAddressVO> userDeptAndWorkAddressVOList = new ArrayList<>();
        for (UserDeptWorkAddress userDeptWorkAddress : userDeptWorkAddressList) {
            UserDeptAndWorkAddressVO userDeptAndWorkAddressVO = new UserDeptAndWorkAddressVO();
            userDeptAndWorkAddressVO.setUserId(userId);
            userDeptAndWorkAddressVO.setDeptId(userDeptWorkAddress.getDeptId());
            String deptName = deptService.getById(userDeptWorkAddress.getDeptId()).getName();
            userDeptAndWorkAddressVO.setDeptName(deptName);
            // 查询工作地点
//            String address = workAddressService.getById(userDeptWorkAddress.getWorkAddressId()).getName();
//            userDeptAndWorkAddressVO.setWorkAddressId(userDeptWorkAddress.getWorkAddressId());
//            userDeptAndWorkAddressVO.setWorkAddressName(address);
//            userDeptAndWorkAddressVOList.add(userDeptAndWorkAddressVO);
        }
        // 查询用户临时部门
        LambdaQueryWrapper<UserTmpDept> userTmpDeptLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userTmpDeptLambdaQueryWrapper.eq(UserTmpDept::getUserId, userId);
        userTmpDeptLambdaQueryWrapper.gt(UserTmpDept::getExpiration, new Date());
        List<UserTmpDept> tempDeptList = userTmpDeptService.list(userTmpDeptLambdaQueryWrapper);
        for (UserTmpDept userTmpDept : tempDeptList) {
            UserDeptAndWorkAddressVO userDeptAndWorkAddressVO = new UserDeptAndWorkAddressVO();
            BeanUtils.copyProperties(userTmpDept, userDeptAndWorkAddressVO);
            userDeptAndWorkAddressVO.setDeptName(deptService.getById(userTmpDept.getDeptId()).getName());
            userDeptAndWorkAddressVO.setWorkAddressName(workAddressService.getById(userTmpDept.getWorkAddressId()).getName());
            userDeptAndWorkAddressVOList.add(userDeptAndWorkAddressVO);
        }
        detail.setUserDeptAndWorkAddressVOList(userDeptAndWorkAddressVOList);
        // 库权限
        List<DrugDepositoryUserAuth> drugDepositoryUserAuthList = drugDepositoryUserAuthService.list(new LambdaQueryWrapper<DrugDepositoryUserAuth>().eq(DrugDepositoryUserAuth::getUserId, userId));
        List<UserDetailVO.DrugDepositoryUserAuthVo> drugDepositoryUserAuthVoList = new ArrayList<>();
        List<DrugDepository> drugDepositoryList = drugDepositoryService.list();
        for (DrugDepository drugDepository : drugDepositoryList) {
            drugDepositoryUserAuthVoList.add(new UserDetailVO.DrugDepositoryUserAuthVo(drugDepository.getId(), drugDepository.getName()));
        }
        for (DrugDepositoryUserAuth drugDepositoryUserAuth : drugDepositoryUserAuthList) {
            // drug depository
            UserDetailVO.DrugDepositoryUserAuthVo drugDepositoryUserAuthVo = drugDepositoryUserAuthVoList.stream().filter(vo -> vo.getDrugDepositoryId().equals(drugDepositoryUserAuth.getDrugDepositoryId())).findFirst().get();
            this.buildOptType(drugDepositoryUserAuth, drugDepositoryUserAuthVo);
        }
        detail.setDrugDepositoryUserAuthList(drugDepositoryUserAuthVoList);
        return ApiResult.success(detail);
    }

    private void buildOptType(DrugDepositoryUserAuth drugDepositoryUserAuth, UserDetailVO.DrugDepositoryUserAuthVo drugDepositoryUserAuthVo) {

        drugDepositoryUserAuthVo.setIsQuery(drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.QUERY.getCode()) ? drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.QUERY.getCode()) : drugDepositoryUserAuthVo.getIsQuery());
        drugDepositoryUserAuthVo.setIsSell(drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.SELL.getCode()) ? drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.SELL.getCode()) : drugDepositoryUserAuthVo.getIsSell());
        drugDepositoryUserAuthVo.setIsInput(drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.INPUT.getCode()) ? drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.INPUT.getCode()) : drugDepositoryUserAuthVo.getIsInput());
        drugDepositoryUserAuthVo.setIsOutput(drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.OUTPUT.getCode()) ? drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.OUTPUT.getCode()) : drugDepositoryUserAuthVo.getIsOutput());
        drugDepositoryUserAuthVo.setIsCheck(drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.CHECK.getCode()) ? drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.CHECK.getCode()) : drugDepositoryUserAuthVo.getIsCheck());
        drugDepositoryUserAuthVo.setIsWriteOff(drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.WRITE_OFF.getCode()) ? drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.WRITE_OFF.getCode()) : drugDepositoryUserAuthVo.getIsWriteOff());
        drugDepositoryUserAuthVo.setIsPurchase(drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.PURCHASE.getCode()) ? drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.PURCHASE.getCode()) : drugDepositoryUserAuthVo.getIsPurchase());
        drugDepositoryUserAuthVo.setIsCostPrice(drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.COST_PRICE.getCode()) ? drugDepositoryUserAuth.getOptType().equals(DrugDepositoryOtpTypeEnum.COST_PRICE.getCode()) : drugDepositoryUserAuthVo.getIsCostPrice());
    }

    @GetMapping("/current-user-detail")
    @ApiOperation(value = "登录用户详情")
    public ApiResult<UserDetailVO> currentUserDetail(HttpServletRequest request) {
        Long userId = JwtUtil.getUserId(request.getHeader(Constant.AUTHORIZATION));
        UserDetailVO detail = userExtendMapper.detail(userId);
        if (StringUtils.isNotBlank(detail.getJobDuty())) {
            List<JobDutyVO> jobDutyList = new ArrayList<>();
            for (String jobDutyId : detail.getJobDuty().split(",")) {
                JobDutyVO jobDutyVO = new JobDutyVO();
                JobDuty jobDuty = jobDutyService.getById(jobDutyId);
                if (Objects.nonNull(jobDuty)) {
                    BeanUtils.copyProperties(jobDuty, jobDutyVO);
                }
                Dept tmpDept = deptService.getById(jobDutyVO.getDeptId());
                jobDutyVO.setDeptName(tmpDept.getName());
                jobDutyList.add(jobDutyVO);
            }
            detail.setJobDutyList(jobDutyList);
        }
        // 查询用户所有菜单权限
        LambdaQueryWrapper<UserMenu> umQueryWrapper = new LambdaQueryWrapper<>();
        umQueryWrapper.eq(UserMenu::getUserId, userId);
        List<UserMenu> list = userMenuService.list(umQueryWrapper);
        List<Long> userMenus = list.stream().map(UserMenu::getMenuId).collect(Collectors.toList());
        detail.setUserMenus(userMenus);

        UserDeptWorkAddressJobOffice userDeptWorkAddressJobOffice = CaffeineUtils.getByUserId(userId);
        detail.setUserDeptWorkAddressJobOffice(userDeptWorkAddressJobOffice);
        // 查询用户部门以及工作地点
        List<UserDeptWorkAddress> userDeptWorkAddressList = userDeptWorkAddressService.list(new LambdaQueryWrapper<UserDeptWorkAddress>().eq(UserDeptWorkAddress::getUserId, userId));
        List<UserDeptAndWorkAddressVO> userDeptAndWorkAddressVOList = new ArrayList<>();
        for (UserDeptWorkAddress userDeptWorkAddress : userDeptWorkAddressList) {
            UserDeptAndWorkAddressVO userDeptAndWorkAddressVO = new UserDeptAndWorkAddressVO();
            userDeptAndWorkAddressVO.setUserId(userId);
            userDeptAndWorkAddressVO.setDeptId(userDeptWorkAddress.getDeptId());
            String deptName = deptService.getById(userDeptWorkAddress.getDeptId()).getName();
            userDeptAndWorkAddressVO.setDeptName(deptName);
            // 查询工作地点
//            String address = workAddressService.getById(userDeptWorkAddress.getWorkAddressId()).getName();
//            userDeptAndWorkAddressVO.setWorkAddressId(userDeptWorkAddress.getWorkAddressId());
//            userDeptAndWorkAddressVO.setAddress(address);
//            userDeptAndWorkAddressVOList.add(userDeptAndWorkAddressVO);
        }
        // 查询用户临时部门
        LambdaQueryWrapper<UserTmpDept> userTmpDeptLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userTmpDeptLambdaQueryWrapper.eq(UserTmpDept::getUserId, userId);
        userTmpDeptLambdaQueryWrapper.gt(UserTmpDept::getExpiration, new Date());
        List<UserTmpDept> tempDeptList = userTmpDeptService.list(userTmpDeptLambdaQueryWrapper);
        for (UserTmpDept userTmpDept : tempDeptList) {
            UserDeptAndWorkAddressVO userDeptAndWorkAddressVO = new UserDeptAndWorkAddressVO();
            BeanUtils.copyProperties(userTmpDept, userDeptAndWorkAddressVO);
            userDeptAndWorkAddressVO.setDeptName(deptService.getById(userTmpDept.getDeptId()).getName());
            userDeptAndWorkAddressVO.setWorkAddressName(workAddressService.getById(userTmpDept.getWorkAddressId()).getName());
            userDeptAndWorkAddressVOList.add(userDeptAndWorkAddressVO);
        }
        detail.setUserDeptAndWorkAddressVOList(userDeptAndWorkAddressVOList);
        return ApiResult.success(detail);
    }

    @PostMapping("/edit")
    @ApiOperation(value = "编辑员工信息")
    @Transactional
    public ApiResult<?> edit(@Valid @RequestBody UserEditReqDTO userEditReqDTO, HttpServletRequest request) {
        User user = new User();
        BeanUtils.copyProperties(userEditReqDTO, user);
        user.setId(userEditReqDTO.getId());
        user.setJobDuty(StringUtils.join(userEditReqDTO.getJobDutyList(), ","));
        user.setJobOffice(StringUtils.join(userEditReqDTO.getJobOfficeList(), ","));
        String userName = "aaa";
        user.setUpdatedBy(userName);
        userService.updateById(user);
        // 删掉用户所在部门
        LambdaQueryWrapper<UserDeptWorkAddress> userDeptWorkAddressQueryWrapper = new LambdaQueryWrapper<>();
        userDeptWorkAddressQueryWrapper.eq(UserDeptWorkAddress::getUserId, userEditReqDTO.getId());
        userDeptWorkAddressService.remove(userDeptWorkAddressQueryWrapper);
        if (!CollectionUtil.isEmpty(userEditReqDTO.getUserDeptAndWorkAddressVOList())) {
            ArrayList<UserDeptWorkAddress> deptList = userEditReqDTO.getUserDeptAndWorkAddressVOList().stream().map(item -> {
                item.setCreatedBy(userName);
                item.setUpdatedBy(userName);
                return item;
            }).collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(UserDeptWorkAddress::getDeptId))), ArrayList::new));
            userDeptWorkAddressService.saveBatch(deptList);
        }
        // 先删掉用户权限
        LambdaQueryWrapper<UserMenu> userQueryWrapper = new LambdaQueryWrapper<>();
        userQueryWrapper.eq(UserMenu::getUserId, userEditReqDTO.getId());
        userMenuService.remove(userQueryWrapper);
        // 再添加用户权限
        List<UserMenu> userMenuList = new ArrayList<>();
        List<Long> menuList = userEditReqDTO.getMenuList();
        if (!CollectionUtil.isEmpty(menuList)) {
            for (Long menuId : menuList) {
                UserMenu userMenu = new UserMenu();
                userMenu.setUserId(userEditReqDTO.getId());
                userMenu.setMenuId(menuId);
                userMenu.setCreatedBy(userName);
                userMenu.setUpdatedBy(userName);
                userMenuList.add(userMenu);
            }
            userMenuService.saveBatch(userMenuList);
        } else {
            List<JobDutyMenu> jobDutyList = jobDutyMenuService.list(new LambdaQueryWrapper<JobDutyMenu>().in(JobDutyMenu::getJobDutyId, userEditReqDTO.getJobDutyList()));
            if (!CollectionUtil.isEmpty(jobDutyList)) {
                List<Long> menuIdList = jobDutyList.stream().map(JobDutyMenu::getMenuId).collect(Collectors.toList());
                for (Long menuId : menuIdList) {
                    UserMenu userMenu = new UserMenu();
                    userMenu.setUserId(userEditReqDTO.getId());
                    userMenu.setMenuId(menuId);
                    userMenu.setCreatedBy(userName);
                    userMenu.setUpdatedBy(userName);
                    userMenuList.add(userMenu);
                }
                userMenuService.saveBatch(userMenuList);
            }
        }
        if (!CollectionUtil.isEmpty(userEditReqDTO.getDrugDepositoryUserAuthList())) {
            drugDepositoryUserAuthService.remove(new LambdaQueryWrapper<DrugDepositoryUserAuth>().eq(DrugDepositoryUserAuth::getUserId, user.getId()));
            List<DrugDepositoryUserAuth> addList = new ArrayList<>();
            for (UserDetailVO.DrugDepositoryUserAuthVo drugDepositoryUserAuthVo : userEditReqDTO.getDrugDepositoryUserAuthList()) {
                if (drugDepositoryUserAuthVo.getIsQuery()) addList.add(new DrugDepositoryUserAuth(user.getId(), drugDepositoryUserAuthVo.getDrugDepositoryId(), DrugDepositoryOtpTypeEnum.QUERY.getCode(), userName, userName));
                if (drugDepositoryUserAuthVo.getIsSell()) addList.add(new DrugDepositoryUserAuth(user.getId(), drugDepositoryUserAuthVo.getDrugDepositoryId(), DrugDepositoryOtpTypeEnum.SELL.getCode(), userName, userName));
                if (drugDepositoryUserAuthVo.getIsInput()) addList.add(new DrugDepositoryUserAuth(user.getId(), drugDepositoryUserAuthVo.getDrugDepositoryId(), DrugDepositoryOtpTypeEnum.INPUT.getCode(), userName, userName));
                if (drugDepositoryUserAuthVo.getIsOutput()) addList.add(new DrugDepositoryUserAuth(user.getId(), drugDepositoryUserAuthVo.getDrugDepositoryId(), DrugDepositoryOtpTypeEnum.OUTPUT.getCode(), userName, userName));
                if (drugDepositoryUserAuthVo.getIsCheck()) addList.add(new DrugDepositoryUserAuth(user.getId(), drugDepositoryUserAuthVo.getDrugDepositoryId(), DrugDepositoryOtpTypeEnum.CHECK.getCode(), userName, userName));
                if (drugDepositoryUserAuthVo.getIsWriteOff()) addList.add(new DrugDepositoryUserAuth(user.getId(), drugDepositoryUserAuthVo.getDrugDepositoryId(), DrugDepositoryOtpTypeEnum.WRITE_OFF.getCode(), userName, userName));
                if (drugDepositoryUserAuthVo.getIsPurchase()) addList.add(new DrugDepositoryUserAuth(user.getId(), drugDepositoryUserAuthVo.getDrugDepositoryId(), DrugDepositoryOtpTypeEnum.PURCHASE.getCode(), userName, userName));
                if (drugDepositoryUserAuthVo.getIsCostPrice()) addList.add(new DrugDepositoryUserAuth(user.getId(), drugDepositoryUserAuthVo.getDrugDepositoryId(), DrugDepositoryOtpTypeEnum.COST_PRICE.getCode(), userName, userName));
            }
            drugDepositoryUserAuthService.saveBatch(addList);
        }
        return ApiResult.success();
    }

    @GetMapping("/jobDuty-user/{jobDuty}")
    @ApiOperation(value = "根据职务查询人员列表")
    public ApiResult<List<User>> jobDutyUser(@PathVariable Long jobDuty) {
        List<User> list = userService.list(new LambdaQueryWrapper<User>().eq(User::getJobDuty, jobDuty));
        return ApiResult.success(list);
    }

    @GetMapping("/user-dept-workAddress-jobOffice/{phoneNumber}")
    @ApiOperation(value = "根据手机号查询用户部门和科室")
    public ApiResult<UserDeptWorkAddressJobOfficeVO> userDeptWorkAddressJobOffice(@PathVariable String phoneNumber) {
        UserDeptWorkAddressJobOfficeVO userDeptWorkAddressJobOfficeVO = new UserDeptWorkAddressJobOfficeVO();
        User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getPhone, phoneNumber));
        if (Objects.isNull(user)) return ApiResult.error(ResponseCodeEnum.USER_NOT_EXIST);
        Long userId = user.getId();
        List<AuditFlow> auditFlows = auditFlowService.list(new LambdaQueryWrapper<AuditFlow>().eq(AuditFlow::getFlowNo, "ZC" + userId));
        long count = auditFlows.stream().filter(one -> AuditStatusEnum.FINISH.getCode().equals(one.getStatus())).count();
        if (count == 0) return ApiResult.error(ResponseCodeEnum.WAIT_AUDIT);
        // 查询用户所在部门
        List<UserDeptWorkAddress> userDeptWorkAddressList = userDeptWorkAddressService.list(new LambdaQueryWrapper<UserDeptWorkAddress>().eq(UserDeptWorkAddress::getUserId, userId));
        List<UserDeptWorkAddressJobOfficeVO.UserDept> userDeptList = new ArrayList<>();
        for (UserDeptWorkAddress userDeptWorkAddress : userDeptWorkAddressList) {
            UserDeptWorkAddressJobOfficeVO.UserDept userDept = new UserDeptWorkAddressJobOfficeVO.UserDept();
            userDept.setDeptId(userDeptWorkAddress.getDeptId());
            userDept.setDeptName(deptService.getById(userDeptWorkAddress.getDeptId()).getName());
            userDeptList.add(userDept);
        }
        // 查询用户临时部门
        LambdaQueryWrapper<UserTmpDept> userTmpDeptLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userTmpDeptLambdaQueryWrapper.eq(UserTmpDept::getUserId, userId);
        userTmpDeptLambdaQueryWrapper.gt(UserTmpDept::getExpiration, new Date());
        List<UserTmpDept> tempDeptList = userTmpDeptService.list(userTmpDeptLambdaQueryWrapper);
        for (UserTmpDept userTmpDept : tempDeptList) {
            UserDeptWorkAddressJobOfficeVO.UserDept userDept = new UserDeptWorkAddressJobOfficeVO.UserDept();
            userDept.setDeptId(userTmpDept.getDeptId());
            userDept.setDeptName(deptService.getById(userTmpDept.getDeptId()).getName());
            userDeptList.add(userDept);
        }

        List<UserDeptWorkAddressJobOfficeVO.UserJobOffice> userJobOfficeList = new ArrayList<>();
        if (user.getJobOffice() != null) {
            String[] jobOfficeList = user.getJobOffice().split(",");
            for (String jobOfficeId : jobOfficeList) {
                JobOffice jobOffice = jobOfficeService.getById(jobOfficeId);
                UserDeptWorkAddressJobOfficeVO.UserJobOffice userJobOffice = new UserDeptWorkAddressJobOfficeVO.UserJobOffice();
                userJobOffice.setJobOfficeId(jobOffice.getId());
                userJobOffice.setJobOfficeName(jobOffice.getName());
                userJobOfficeList.add(userJobOffice);
            }
        }

        List<UserDeptWorkAddressJobOfficeVO.UserJobDuty> userJobDutyList = new ArrayList<>();
        if (user.getJobDuty() != null) {
            String[] jobDutyList = user.getJobDuty().split(",");
            for (String jobDutyId : jobDutyList) {
                JobDuty jobDuty = jobDutyService.getById(jobDutyId);
                UserDeptWorkAddressJobOfficeVO.UserJobDuty userJobDuty = new UserDeptWorkAddressJobOfficeVO.UserJobDuty();
                userJobDuty.setJobDutyId(jobDuty.getId());
                userJobDuty.setJobDutyName(jobDuty.getName());
                userJobDuty.setDeptId(jobDuty.getDeptId());
                userJobDutyList.add(userJobDuty);
            }
        }

        userDeptWorkAddressJobOfficeVO.setUserDeptList(userDeptList);
        userDeptWorkAddressJobOfficeVO.setUserJobOfficeList(userJobOfficeList);
        userDeptWorkAddressJobOfficeVO.setUserJobDutyList(userJobDutyList);
        return ApiResult.success(userDeptWorkAddressJobOfficeVO);
    }

    @GetMapping("/dept-userList/{deptId}")
    @ApiOperation(value = "根据部门查询登录的医生列表，职务里有'医生'字样的user")
    public ApiResult<?> userDeptWorkAddressJobOffice(@PathVariable Long deptId) {
        List<User> doctorUserList = new ArrayList<>();
        List<UserDeptWorkAddressJobOffice> list = (List<UserDeptWorkAddressJobOffice>)CaffeineUtils.get(USER_CACHE);
        System.out.println("list: >>"+list);
        List<Long> userIdList = list.stream().filter(u -> u.getDeptId().equals(deptId) && u.getIsVisit().equals(1)).map(UserDeptWorkAddressJobOffice::getUserId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(userIdList)) return ApiResult.success(doctorUserList);
        doctorUserList = userService.list(new LambdaQueryWrapper<User>().in(User::getId, userIdList));
//        Map<Long, String> jobDuty = jobDutyService.list().stream().collect(Collectors.toMap(JobDuty::getId, JobDuty::getName));
//        for (User user : userList) {
//            String[] split = user.getJobDuty().split(",");
//            for (String s : split) {
//                if (jobDuty.get(Long.valueOf(s)).equals("医生")) {
//                    doctorUserList.add(user);
//                    break;
//                }
//            }
//        }
//        return ApiResult.success(BeanUtil.copyToList(doctorUserList, DeptUserListVO.class));
        return ApiResult.success(doctorUserList);
    }

    @GetMapping("/user-login-info/{userId}")
    @ApiOperation(value = "根据userid 查询登录信息")
    public ApiResult<UserDetailVO> userLoginInfo(@PathVariable Long userId) {
        // 将用户登录信息存储在本地缓存
        UserDetailVO detail = new UserDetailVO();
        UserDeptWorkAddressJobOffice userDeptWorkAddressJobOffice = CaffeineUtils.getByUserId(userId);
//        WorkAddress workAddress = workAddressService.getById(userDeptWorkAddressJobOffice.getWorkAddressId());
//        userDeptWorkAddressJobOffice.setWorkAddressName(workAddress.getName());
        detail.setUserDeptWorkAddressJobOffice(userDeptWorkAddressJobOffice);
        return ApiResult.success(detail);
    }

}
